package cn.ydxiaoshuai.common.util;

import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;

/**
 * @author xavier
 * @className ImageUtil
 * @Description 图片缩放
 * @Date 2020/9/29-9:58
 **/
@Slf4j
public class ImageUtil {
    /**
     * 缩放比例系数
     */
    private static double SCALING = 0.56;
    /**
     * 符合base64的宽
     */
    private static int MAX_WIDTH = 560;
    /**
     * 最大高
     */
    private static int MAX_HEIGHT = 1000;

    /**
     * @author xavier
     * @Description 根据图片公网地址转BufferedImage
     * @Date  2020/9/29 10:52
     * @param url 图片公网地址
     * @return java.awt.image.BufferedImage
     **/
    public static BufferedImage imgUrlConvertBufferedImage(String url) throws Exception {
        URL urls = new URL(url);
        Image image = Toolkit.getDefaultToolkit().getImage(urls);
        BufferedImage bufferedImage = toBufferedImage(image);
        return bufferedImage;
    }
    /**
     * @author xavier
     * @Description 根据BufferedImage处理图片并返回byte[]
     * @Date  2020/9/29 10:55
     * @param bufferedImage
     * @return byte[]
     **/
    public static byte[] zoomImageByte(BufferedImage bufferedImage) throws Exception {
        ByteArrayOutputStream outputStreamZoom = new ByteArrayOutputStream();
        ByteArrayOutputStream outputStreamSource = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", outputStreamSource);
        BufferedImage bufferedImageZoom = zoomImage(outputStreamSource.toByteArray());
        //写入缩减后的图片
        ImageIO.write(bufferedImageZoom, "jpg", outputStreamZoom);
        return outputStreamZoom.toByteArray();
    }

    /**
     * @author xavier
     * @Description 根据byte[]处理图片并返回byte[]
     * @Date  2020/9/29 10:55
     * @param src
     * @return byte[]
     **/
    public static byte[] zoomImageByte(byte[] src) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        BufferedImage bufferedImage = zoomImage(src);
        //写入缩减后的图片
        ImageIO.write(bufferedImage, "jpg", outputStream);
        return outputStream.toByteArray();
    }

    /**
     * 图片缩放 仅适用于微信内容图片安全检测使用
     *
     * @param src 为源文件byte
     */
    public static BufferedImage zoomImage(byte[] src) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(src);
        double wr = 0, hr = 0;
        BufferedImage bufferedImage = null;
        //读取图片
        BufferedImage bufImg = ImageIO.read(in);
        int height = bufImg.getHeight();
        int width = bufImg.getWidth();
        int cHeight = height;
        int cWidth = width;
        double Scaling = width / height;
        if (Scaling < SCALING) {
            if (height > MAX_HEIGHT) {
                cHeight = MAX_HEIGHT;
                cWidth = (width * MAX_HEIGHT) / height;
            }
            //以宽为缩放比例
        } else {
            if (width > MAX_WIDTH) {
                cWidth = MAX_WIDTH;
                cHeight = (height * MAX_WIDTH) / width;
            }
        }
        //获取缩放后的宽高
        log.info("宽{},高{}", cWidth, cHeight);
        //设置缩放目标图片模板
        Image Itemp = bufImg.getScaledInstance(width, cHeight, BufferedImage.SCALE_SMOOTH);
        //获取缩放比例
        wr = cWidth * 1.0 / width;
        hr = cHeight * 1.0 / height;
        log.info("宽比例{},高比例{}", wr, hr);
        AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
        Itemp = ato.filter(bufImg, null);
        try {
            //写入缩减后的图片
            ImageIO.write((BufferedImage) Itemp, "jpg", outputStream);
            ByteArrayInputStream inNew = new ByteArrayInputStream(outputStream.toByteArray());
            bufferedImage = ImageIO.read(inNew);
        } catch (Exception ex) {
            log.info("缩放图片异常{}", ex.getMessage());
        } finally {
            if (null != outputStream) {
                outputStream.close();
            }
            if (null != in) {
                in.close();
            }
        }
        return bufferedImage;
    }

    /**
     * @author xavier
     * @Description Image转BufferedImage
     * @Date  2020/9/29 10:47
     * @param image 通过url获取的image对象
     * @return java.awt.image.BufferedImage
     **/
    public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment
                .getLocalGraphicsEnvironment();
        try {
            int transparency = Transparency.OPAQUE;
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null),
                    image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            bimage = new BufferedImage(image.getWidth(null),
                    image.getHeight(null), type);
        }
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return bimage;
    }
}
